package net.atomarrow.services;

import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Map;

import net.atomarrow.bean.Pager;
import net.atomarrow.db.parser.Conditions;
import net.atomarrow.domains.Domain;

/**
 * 业务层接口
 * 
 * @author Michael
 * 
 */
public interface IService {
	/**
	 * 添加实体
	 * 
	 * @param domain
	 *            实体
	 * @return Serializable 数据库中主键ID
	 */
    Serializable add(Domain domain);
	/**
	 * 添加实体
	 * 
	 * @param domain
	 *            实体
	 * @return Serializable 数据库中主键ID
	 */
    Serializable add(String tableName, Domain domain);

	/**
	 * 删除实体
	 * 
	 * @param domain
	 *            实体
	 */
    int del(Domain domain);

	/**
	 * 修改实体
	 * 
	 * @param domain
	 *            实体
	 */
    int modify(Domain domain);
	/**
	 * 修改实体
	 * 
	 * @param o
	 *            实体
	 */
    int modify(String tableName, Domain domain);

	/**
	 * 根据id删除
	 * 
	 * @param <T>
	 * @param entityClass
	 * @param id
	 * @return
	 */
    <T> int delById(Class<T> entityClass, Serializable id);
	/**
	 * 根据id删除
	 * 
	 * @param <T>
	 * @param className
	 * @param id
	 * @return
	 */
    <T> int delById(String className, Serializable id);

	/**
	 * 根据ID取得实体
	 * 
	 * @param <T>
	 * @param entityClass
	 *            实体类
	 * @param id
	 *            主键ID
	 * @return T
	 */
    <T> T getById(Class<T> entityClass, Serializable id);
	/**
	 * 根据ID取得实体
	 * 
	 * @param <T>
	 * @param tableName
	 *            实体类名
	 * @param id
	 *            主键ID
	 * @return T
	 */
    <T> T getById(String tableName, Serializable id);
	/**
	 * 根据条件取得实体列
	 * 
	 * @param <T>
	 * @param entityClass
	 *            实体类
	 * @param id
	 *            主键ID
	 * @return T
	 */
    <T> T getColumn(Conditions conditions, String attribute);

	/**
	 * 批量添加
	 * 
	 * @param dataList
	 *            实体表
	 * @return boolean 操作完成状态
	 */
    boolean addByBatch(final List<? extends Domain> dataList);

	/**
	 * 根据条件搜索list返回实体对象集合只包含指定列信息
	 * 
	 * @param <T>
	 * @param conditions
	 *            条件
	 * @param columns
	 *            搜索返回列
	 * @return List<T>
	 */
    <T> List<T> getListWithColumn(Conditions conditions, String[] columns);

	/**
	 * 根据条件搜索list
	 * 
	 * @param <T>
	 * @param conditions
	 *            条件
	 * @return List<T>
	 */
    <T> List<T> getList(Conditions conditions);

	/**
	 * 批量删除
	 * 
	 * @param conditons
	 *            条件
	 * @return 执行的条数
	 */
    int delByBatch(Conditions conditions);

	/**
	 * 根据条件搜索list并分页，返回内容只包含规定的列
	 * 
	 * @param <T>
	 * @param conditions
	 *            搜索条件
	 * @param columns
	 *            搜索返回列
	 * @param pager
	 *            分页条件
	 * @return List 数据
	 */
    <T> List<T> getListWithColumnByPage(Conditions conditions,
                                        String[] columns, Pager pager);

	/**
	 * 根据条件搜索list并分页
	 * 
	 * @param <T>
	 * @param conditions
	 *            搜索条件
	 * @param pager
	 *            分页条件
	 * @return List 数据
	 */
    <T> List<T> getListByPage(Conditions conditions, Pager pager);

	/**
	 * 根据条件得到某列数据集
	 * 
	 * @param <T>
	 * @param conditions
	 *            搜索条件
	 * @param attribute
	 *            返回的列
	 * @param pager
	 *            分页信息
	 * @return List 返回的列数据集
	 */
    <T> List<T> getColumnListByPage(Conditions conditions,
                                    String attribute, Pager pager);
	
	/**
	 * 根据条件得到某列不重复的数据集
	 * 
	 * @param <T>
	 * @param conditions
	 *            搜索条件
	 * @param attribute
	 *            返回的列
	 * @param pager
	 *            分页信息
	 * @return List 返回的列(不重复)数据集
	 */
    <T> List<T> getColumnDistinctListByPage(Conditions conditions,
                                            String attribute, Pager pager);

	/**
	 * 根据条件得到某列数据集
	 * 
	 * @param <T>
	 * @param conditions
	 *            搜索条件
	 * @param attribute
	 *            返回的列
	 * @return List 返回的列数据集
	 */
    <T> List<T> getColumnList(Conditions conditions, String attribute);
	/**
	 * 根据条件得到某列不重复的数据集
	 * 
	 * @param <T>
	 * @param conditions
	 *            搜索条件
	 * @param attribute
	 *            返回的列
	 * @return List 返回的列（不重复）数据集
	 */
    <T> List<T> getColumnDistinctList(Conditions conditions, String attribute);

	/**
	 * 根据条件得到某列不重复值数据集
	 * 
	 * @param <T>
	 * @param conditions
	 *            搜索条件
	 * @param attribute
	 *            不重复列
	 * @return List 数据
	 */
    <T> List<T> getDistinctList(Conditions conditions, String attribute);
	/**
	 * 根据条件得到某列不重复值数据集
	 * 
	 * @param <T>
	 * @param conditions
	 *            搜索条件
	 * @param attribute
	 *            不重复列
	 * @return List 数据
	 */
    <T> List<T> getDistinctListPage(Conditions conditions, String attribute, Pager pager);
	/**
     * 查询返回Double
     * @param conditions
     * @return
     */
    Double getDouble(Conditions conditions);
    /**
     * 查询返回Integer
     * @param conditions
     * @return
     */
    Integer getInteger(Conditions conditions);
    /**
     * 查询返回Long
     * @param conditions
     * @return
     */
    Long getLong(Conditions conditions);
    /**
     * 查询返回Date
     * @param conditions
     * @return
     */
    Date getDate(Conditions conditions);

    /**
     * 根据条件得到相应列的最小值
     * 
     * @param conditions
     * @param attribute
     * @return double 数值
     */
    Double getMin(Conditions conditions, String attribute);
       /**
     * 根据条件得到相应列的最小值的实体
     * 
     * @param conditions
     * @param attribute
     * @return 实体类
     */
       <T> T getMinDomain(Conditions conditions, String attribute);
	/**
	 * 根据条件得到相应列的最大值
	 * 
	 * @param conditions
	 * @param attribute
	 * @return double 数值
	 */
    Double getMax(Conditions conditions, String attribute);

	/**
	 * 根据条件得到相应列的最大值的实体
	 * 
	 * @param conditions
	 * @param attribute
	 * @return 实体类
	 */
    <T> T getMaxDomain(Conditions conditions, String attribute);

	/**
	 * 根据条件得到数量
	 * 
	 * @param conditoins
	 * @return double 符合条件总数
	 */
    int getCount(Conditions conditions);

	/**
	 * 更新某列信息
	 * 
	 * @param conditions
	 *            搜索条件
	 * @param columns
	 *            更新列为key，更新内容为value
	 * @return 执行的条数
	 */
    int modifyWithColumn(Conditions conditions,
                         Map<String, Serializable> columns);
	/**
	 * 更新某列信息
	 * 
	 * @param conditions
	 *            搜索条件
	 * @param keyValues
	 *            基数列为key，偶数列为value，按顺序排列
	 * @return
	 */
    int modifyWithColumn(Conditions conditions,
                         Serializable[] keyValues);

	/**
	 * 批量更新
	 * 
	 * @param dataList
	 * @return boolean
	 */
    boolean modifyByBatch(List<? extends Domain> dataList);
	/**
	 * 批量更新
	 * @param tableName
	 * @param dataList
	 * @return
	 */
    boolean modifyByBatch(String tableName, List<? extends Domain> dataList);
	/**
	 * 批量更新指定列
	 * @param dataList 数据列表
	 * @param cols 需要更新的列
	 * @return
	 */
    boolean modifyByBatchWithColumn(List<? extends Domain> dataList, String[] cols);
	/**
	 * 批量更新指定列
	 * @param tableName 更新的表名
	 * @param dataList 数据列表
	 * @param cols 需要更新的列
	 * @return
	 */
    boolean modifyByBatchWithColumn(String tableName, List<? extends Domain> dataList, String[] cols);

	/**
	 * 添加或更新
	 * 
	 * @param datas
	 * @return boolean
	 */
    boolean saveOrUpdate(List<? extends Domain> datas);
	
	/**
	 * 添加或更新
	 * 
	 * @param data
	 */
    void saveOrUpdate(Domain data);
	/**
	 * 添加或更新
	 * 
	 * @param datas
	 * @return boolean
	 */
    boolean saveOrUpdate(String tableName, List<? extends Domain> datas);

	/**
	 * 添加或更新
	 * 
	 * @param data
	 */
    void saveOrUpdate(String tableName, Domain data);
	
	/**
	 * 根据条件得到数量和
	 * 
	 * @param conditions
	 *            条件
	 * @param attribute
	 *            求和属性列
	 * @return
	 */
    double getSum(Conditions conditions, String attribute);

	/**
	 * 根据条件将某列使用分隔符隔开进行合并<br>
	 * 
	 * 如：id列使用","分割符号，得到的结果为 1,2,3,4,5<br>
	 * @param conditions
	 *            条件
	 * @param attribute
	 *            求和属性列
	 * @param separator
	 * 			  分隔符
	 * @return
	 */
    String getGroupConcat(Conditions conditions, String attribute, String separator);

//	/**
//	 * 根据条件搜索返回单个实体，先搜索缓存，后搜索数据库
//	 * 
//	 * @param <T>
//	 * @param conditions
//	 *            条件
//	 * @param cache
//	 *            缓存
//	 * @param reg
//	 *            匹配原则
//	 * @return
//	 */
//	public <T> T getOne(Conditions conditions, Map cache, String[] reg);
//
//	/**
//	 * 根据条件搜索返回单个实体，先搜索缓存，后搜索数据库
//	 * 
//	 * @param <T>
//	 * @param conditions
//	 *            搜索条件
//	 * @param cacheName
//	 *            缓存名称
//	 * @param key
//	 *            缓存key字段
//	 * @return
//	 */
//	public <T> T getOne(Conditions conditions, String cacheName, String key);

	/**
	 * 根据条件搜索返回单个实体
	 * 
	 * @param <T>
	 * @param conditions
	 *            条件
	 * @return T
	 */
    <T> T getOne(Conditions conditions);

	/**
	 * JDBC批量添加
	 * 
	 * @param <T>
	 * @param clazz
	 * @param dataList
	 * @return boolean
	 */
    <T extends Domain> boolean addByBatch(final Class<T> clazz,
                                          final List<T> dataList);
	/**
	 * JDBC批量添加
	 * 
	 * @param <T>
	 * @param tableName
	 * @param dataList
	 * @return boolean
	 */
    boolean addByBatch(String tableName,
                       final List<? extends Domain> dataList);

	/**
	 * 执行语句 如create drop 
	 */
    void execute(String sql);
	/**
	 * 执行更新语句 如 insert update delete
	 * 
	 * @param sql
	 * @return int 执行的语句条数
	 */
    int executeUpdate(String sql, Object[] params);
	/**
	 * 检查重复
	 * @param clazz
	 * @param args
	 * @return
	 */
    boolean checkMultiExist(Class clazz, Serializable... args);
	/**
	 * 检查重复
	 * @param clazz
	 * @param exceptId
	 * @param args
	 * @return
	 */
    boolean checkMultiExistWithExceptId(Class clazz, Serializable exceptId, Serializable... args);
	
	/**
	 * 检查重复
	 * @param tableName
	 * @param args
	 * @return
	 */
    boolean checkMultiExist(String tableName, Serializable... args);
	/**
	 * 检查重复
	 * @param tableName
	 * @param exceptId
	 * @param args
	 * @return
	 */
    boolean checkMultiExistWithExceptId(String tableName, Serializable exceptId, Serializable... args);
	/**
	 * 检查重复
	 * @param clazz
	 * @param args
	 * @return
	 */
    boolean checkMultiExistByOr(Class clazz, Serializable... args);
	/**
	 * 检查重复
	 * @param clazz
	 * @param exceptId
	 * @param args
	 * @return
	 */
    boolean checkMultiExistWithExceptIdByOr(Class clazz, Serializable exceptId, Serializable... args);
	
	/**
	 * 检查重复
	 * @param tableName
	 * @param args
	 * @return
	 */
    boolean checkMultiExistByOr(String tableName, Serializable... args);
	/**
	 * 检查重复
	 * @param tableName
	 * @param exceptId
	 * @param args
	 * @return
	 */
    boolean checkMultiExistWithExceptIdByOr(String tableName, Serializable exceptId, Serializable... args);
	
	/**
	 * 检查重复
	 * @param tableName 实体名
	 * @param colName 字段名
	 * @param value  字段值
	 * @param exceptId 排除id
	 * @return
	 */
    boolean checkExist(Class clazz, String colName, Serializable value, Serializable exceptId);
	/**
	 * 检查重复
	 * @param tableName 实体名
	 * @param colName 字段名
	 * @param value  字段值
	 * @param exceptId 排除id
	 * @return
	 */
    boolean checkExist(Class clazz, String colName, Serializable value);
	/**
	 * 检查重复
	 * @param tableName 实体名
	 * @param colName 字段名
	 * @param value  字段值
	 * @param exceptId 排除id
	 * @return
	 */
    boolean checkExist(String tableName, String colName, Serializable value, Serializable exceptId);
	/**
	 * 检查重复
	 * @param tableName 实体名
	 * @param colName 字段名
	 * @param value  字段值
	 * @param exceptId 排除id
	 * @return
	 */
    boolean checkExist(String tableName, String colName, Serializable value);
	/**
	 * 获得去重的数量
	 * @param conditions
	 * @param attribute
	 * @return
	 */
	int getDistinctCount(Conditions conditions, String attribute);
	/**
	 * 将每行的列结果放在map中，行结果放在list中返回
	 * @param conditions
	 * @return
	 */
	List<Map<String, Object>> getMapList(Conditions conditions);
}
